package com.yanqu.road.server.manger.union;

import com.yanqu.road.server.GameServer;
import com.yanqu.road.server.gameplayer.module.activity.tomb.TombMgr;
import com.yanqu.road.server.manger.activity.douluodalu.DouLuoDaLuMgr;
import com.yanqu.road.server.manger.activity.rankunionwar.RankUnionWarMgr;
import com.yanqu.road.server.manger.activity.seacraft.SeacraftSouthSeaMgr;
import com.yanqu.road.server.pb.UnionPb;
import com.yanqu.road.logic.config.GameConfig;
import com.yanqu.road.entity.enums.eUnionPosition;
import com.yanqu.road.entity.player.UserInfo;
import com.yanqu.road.entity.union.UnionInfo;
import com.yanqu.road.entity.union.UnionJoinApply;
import com.yanqu.road.entity.union.UnionMember;
import com.yanqu.road.pb.union.UnionProto;
import com.yanqu.road.server.TempMgr;
import com.yanqu.road.server.gameplayer.GamePlayer;
import com.yanqu.road.server.gameplayer.module.union.UnionModule;
import com.yanqu.road.server.manger.config.UnionConfigMgr;
import com.yanqu.road.server.manger.player.UserMgr;
import com.yanqu.road.server.manger.player.GamePlayerMgr;
import com.yanqu.road.server.protocol.GameErrorCode;
import com.yanqu.road.server.protocol.Protocol;
import com.yanqu.road.utils.string.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class UnionJoinApplyMgr extends TempMgr {

    private static Object lockObj = new Object();

    private static Map<String, Map<Long, UnionJoinApply>> unionJoinApplyMap;

    @Override
    public boolean reloadData() {
        unionJoinApplyMap = new ConcurrentHashMap<>();
        return true;
    }

    @Override
    public boolean init() throws Exception {
        return reload();
    }

    @Override
    public boolean reloadConfig() throws Exception {
        return true;
    }

    @Override
    public boolean stop() {
        return false;
    }

    public static int addUnionJoinApply(GamePlayer player, String unionUid) {
        synchronized (lockObj) {
            if (!unionJoinApplyMap.containsKey(unionUid)) {
                unionJoinApplyMap.put(unionUid, new ConcurrentHashMap<>());
            }
            Map<Long, UnionJoinApply> applyMap = getUnionJoinApplyMap(unionUid);
            if (applyMap.containsKey(player.getUserId())) {
                return GameErrorCode.E_UNION_JOIN_APPLY_EXIST;
            }
            if (applyMap.size() >= GameConfig.UNION_JOIN_APPLY_MAX_COUNT) {
                return GameErrorCode.E_UNION_JOIN_APPLY_FULL;
            }
            if(!SeacraftSouthSeaMgr.canInAndOutUnion(unionUid)){
                return GameErrorCode.E_SEACRAFT_SOUTH_SEA_ACTIVITY_CAN_NOT_JOIN;
            }
            if(!RankUnionWarMgr.canJoinUnion(unionUid)){
                return GameErrorCode.E_RANKUNIONWAR_ACTIVITY_CAN_NOT_JOIN;
            }

            UnionInfo unionInfo = UnionMgr.getUnionInfo(unionUid);
            if (null == unionInfo) {
                return GameErrorCode.E_UNION_NO_FOUND;
            }

            if (UnionMgr.getUnionMemberCount(unionUid) >= UnionConfigMgr.getMaxMemberCount(unionInfo.getExperience())) {
                return GameErrorCode.E_UNION_MEMBER_FULL;
            }

            int applyTitleLimit = unionInfo.getApplyTitleLimit();
            if (player.getTitleId() < applyTitleLimit) {
                return GameErrorCode.E_UNION_APPLY_TITLE_LIMIT;
            }

            UnionJoinApply unionJoinApply = new UnionJoinApply();
            unionJoinApply.setUnionUid(unionUid);
            unionJoinApply.setUserId(player.getUserId());
            unionJoinApply.setApplyTime(System.currentTimeMillis() / 1000);

            UserInfo userInfo = player.getUserInfo();
            unionJoinApply.setUserBaseInfo(UserMgr.parseUserBaseInfo(userInfo, GameServer.getInstance().getServerId()));
            applyMap.put(player.getUserId(), unionJoinApply);

            player.getModule(UnionModule.class).addApplyUnionUid(unionUid);
            //同步请求(给族长和副族长同步)
            syncJoinApply(unionUid, unionJoinApply);
        }
        return 0;
    }

    public static int agreeJoinApply(GamePlayer player, String unionUid, long applyUserId) {
        synchronized (lockObj){
            UnionJoinApply apply = UnionJoinApplyMgr.getUnionJoinApply(unionUid, applyUserId);
            if(apply == null){
                return GameErrorCode.E_UNION_JOIN_APPLY_NO_FOUND;
            }
        }
        int result = UnionMgr.addUnionMember(player, unionUid, applyUserId);
        if (0 == result) {
            removeJoinApply(unionUid, applyUserId);
            DouLuoDaLuMgr.unionChange(applyUserId);
        }
        return result;
    }

    public static void removeAllJoinApply(String unionUid) {
        List<UnionJoinApply> syncList = new ArrayList<>();
        synchronized (lockObj) {
            Map<Long, UnionJoinApply> applyMap = getUnionJoinApplyMap(unionUid);
            if (null != applyMap) {
                for (UnionJoinApply apply : applyMap.values()) {
                    apply.setDelete(true);
                    syncList.add(apply);
                }
                syncJoinApply(null, unionUid, syncList);
                unionJoinApplyMap.put(unionUid, new ConcurrentHashMap<>());
            }
        }
        for(UnionJoinApply apply : syncList) {
            //移除记录
            UnionMember applyMember = UnionMgr.getUnionMember("", apply.getUserId());
            if (null != applyMember) {
                applyMember.removeApplyUnionUid(unionUid);
                GamePlayer applyPlayer = GamePlayerMgr.getOnlinePlayer(apply.getUserId());
                if (null != applyPlayer) {
                    applyPlayer.getModule(UnionModule.class).syncUnionMember(applyMember);
                }
            }
        }
    }

    public static int removeJoinApply(String unionUid, long applyUserId) {
        synchronized (lockObj) {
            Map<Long, UnionJoinApply> applyMap = getUnionJoinApplyMap(unionUid);
            if(null == applyMap) {
                return GameErrorCode.E_UNION_JOIN_APPLY_NO_FOUND;
            }
            UnionJoinApply apply = applyMap.get(applyUserId);
            if(null == apply){
                return GameErrorCode.E_UNION_JOIN_APPLY_NO_FOUND;
            }
            apply.setDelete(true);
            syncJoinApply(unionUid, apply);
            applyMap.remove(applyUserId);
            //移除记录
            UnionMember applyMember = UnionMgr.getUnionMember("", applyUserId);
            if(null == applyMember){
                UserInfo userInfo = UserMgr.getUserInfo(applyUserId);
                if(null != userInfo && !StringUtils.isNullOrEmpty(userInfo.getUnionUid())){
                    applyMember = UnionMgr.getUnionMember(userInfo.getUnionUid(), applyUserId);
                }
            }
            if(null != applyMember) {
                applyMember.removeApplyUnionUid(unionUid);
                GamePlayer applyPlayer = GamePlayerMgr.getOnlinePlayer(applyUserId);
                if(null != applyPlayer){
                    applyPlayer.getModule(UnionModule.class).syncUnionMember(applyMember);
                }
            }
            return 0;
        }

    }

    public static void sendJoinApplyList(GamePlayer player, String unionUid) {
        Map<Long, UnionJoinApply> applyMap = getUnionJoinApplyMap(unionUid);
        if (null != applyMap) {
            syncJoinApply(player, unionUid, new ArrayList<>(applyMap.values()));
        }
    }

    public static void syncJoinApply(String unionUid, UnionJoinApply unionJoinApply){
        if(null != unionJoinApply){
            List<UnionJoinApply> syncList = new ArrayList<>();
            syncList.add(unionJoinApply);
            syncJoinApply(null, unionUid, syncList);
        }
    }

    public static void syncJoinApply(GamePlayer player, String unionUid, List<UnionJoinApply> unionJoinApplyList){
        UnionProto.UnionJoinApplyListMsg.Builder msg = UnionPb.parseUnionJoinApplyListMsg(unionJoinApplyList);
        if(null != player){
            player.sendPacket(Protocol.U_UNION_JOIN_APPLY_SYNC, msg);
        }else {
            Map<Long, UnionMember> memberMap = UnionMgr.getUnionMemberMap(unionUid);
            if(null != memberMap) {
                for (UnionMember member : memberMap.values()) {
                    if (member.getPosition() == eUnionPosition.Master.getValue() || member.getPosition() == eUnionPosition.DeputyMaster.getValue()) {
                        GamePlayer onlinePlayer = GamePlayerMgr.getOnlinePlayer(member.getUserId());
                        if (null != onlinePlayer) {
                            onlinePlayer.sendPacket(Protocol.U_UNION_JOIN_APPLY_SYNC, msg);
                        }
                    }
                }
            }
        }
    }

    public static Map<Long, UnionJoinApply> getUnionJoinApplyMap(String unionUid){
        return unionJoinApplyMap.get(unionUid);
    }

    public static UnionJoinApply getUnionJoinApply(String unionUid, long applyUserId){
        Map<Long, UnionJoinApply> applyMap = getUnionJoinApplyMap(unionUid);
        if(null == applyMap) {
            return null;
        }
        return applyMap.get(applyUserId);
    }
}
